package customerEnter.Frame.JDBCDao.Processor;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import org.springframework.jdbc.support.rowset.SqlRowSet;
import org.springframework.jdbc.support.rowset.SqlRowSetMetaData;

import customerEnter.Frame.Annotation.FrameAttributes;
import customerEnter.Frame.Annotation.FrameExtraAttributes;
import customerEnter.Frame.DaoDataTransmission.DaoFramePameTransmission;
import customerEnter.Frame.DaoDataTransmission.PagingParametersResult;
import customerEnter.Frame.JDBCDao.util.DaoFrameUtil;
import customerEnter.Frame.Utils.Log4j;
import customerEnter.tool.WhetherToEmpty;

/**
 * 轉換成list數據
 * 
 * 类名称：ListProcessorImpl 类描述： 创建人：dy 创建时间：2016-4-30 上午10:10:42
 * 
 */
@SuppressWarnings({ "unchecked" })
public class ProcessorImpl implements ResultProcessor {
	/**
	 * 設置表結構和相對應的類結構
	 */
	@SuppressWarnings("rawtypes")
	private <T, K> void NewInstanceValues(DaoFramePameTransmission<T, K> daoFramePameTransmission,
			Map<String, Class<?>> map, Class<?> class1) {

		daoFramePameTransmission.DaoFramelistOther.clear();
		SqlRowSetMetaData resultSetMetaData = daoFramePameTransmission.sqlRowSet.getMetaData();
		if (WhetherToEmpty.ObjectWhetherToEmpty(daoFramePameTransmission.getColumnNameMap())) {
			daoFramePameTransmission.setColumnNameMap(new HashMap<String, String>());
		}
		if (WhetherToEmpty.ObjectWhetherToEmpty(daoFramePameTransmission.getBeanAttributes())) {
			daoFramePameTransmission.setBeanAttributes(new HashMap<String, Object>());
		}
		if (WhetherToEmpty.ListWhetherToEmpty(daoFramePameTransmission.listFields)) {
			daoFramePameTransmission.listFields = new ArrayList<Field>();
		}
		for (int i = 1; i <= resultSetMetaData.getColumnCount(); i++) {
			String keyAndValue = resultSetMetaData.getColumnName(i);
			daoFramePameTransmission.getColumnNameMap().put(keyAndValue, keyAndValue);
		}

		for (Field field : class1.getDeclaredFields()) {
			Annotation annotation = field.getAnnotation(FrameAttributes.class);
			if (!WhetherToEmpty.ObjectWhetherToEmpty(annotation)) {
				FrameAttributes frameAttributes = (FrameAttributes) annotation;
				map.put(frameAttributes.ClassName().getName(), frameAttributes.ClassName());
			}
		}
		map.put(class1.getName(), class1);
		for (Entry<String, Class<?>> entry : map.entrySet()) {
			Field[] fields = entry.getValue().getDeclaredFields();
			for (Field field : fields) {
				daoFramePameTransmission.listFields.add(field);
			}
		}
		daoFramePameTransmission.setPagingParametersResult(new PagingParametersResult());
	}

	/**
	 * 循環賦值給類 返回list數據
	 */
	public <T, K> void ProcessorList(DaoFramePameTransmission<T, K> daoFramePameTransmission) {
		Log4j.setLog4j(this.getClass());
		try {
			final Class<?> class1 = daoFramePameTransmission.cls;
			Map<String, Class<?>> map = new HashMap<String, Class<?>>();
			NewInstanceValues(daoFramePameTransmission, map, class1);// 設置表結構和相對應的類結構
			daoFramePameTransmission.Counter = 0;

			while (daoFramePameTransmission.sqlRowSet.next()) {
				Object object = class1.newInstance(); // 生成新bean 放入list
				/**
				 * 反射bean属性 放入 object
				 */
				for (Entry<String, Class<?>> entry : map.entrySet()) {
					if (!class1.getName().equals(entry.getValue().getName())) {
						daoFramePameTransmission.getBeanAttributes().put(entry.getValue().getName(),
								entry.getValue().newInstance());
					}
				}
				daoFramePameTransmission.Counter++;
				daoFramePameTransmission.getBeanAttributes().put(class1.getName(), object);
				setObject(daoFramePameTransmission, object);
				daoFramePameTransmission.DaoFramelistOther.add(object);
				daoFramePameTransmission.cls = class1;
			}
			// System.out.println(size);
			// System.out.println(daoFramePameTransmission.Counter);
		} catch (Exception e) {
			Log4j.Log4jOutInfo(e.getMessage());
		}
		colsDaoFramePameTransmission(daoFramePameTransmission);
	}

	private <T, K> void setObject(DaoFramePameTransmission<T, K> daoFramePameTransmission, Object object) {
		try {
			setFileObject(object, daoFramePameTransmission);

			String clsSuperName = daoFramePameTransmission.cls.getSuperclass().getName();

			if (!WhetherToEmpty.StringWhetherToEmpty(clsSuperName) && !"java.lang.Object".equals(clsSuperName)) {
				daoFramePameTransmission.cls = daoFramePameTransmission.cls.getSuperclass();
				setObject(daoFramePameTransmission, object);
			}
		} catch (Exception e) {
			Log4j.Log4jOutInfo("轉換失敗");
		}
	}

	/**
	 * 反射數據
	 */
	private <T, K> void setFileObject(Object object, DaoFramePameTransmission<T, K> daoFramePameTransmission) {
		/**
		 * 類屬性的反射
		 * 
		 * 类名称：ObjectFieldImpl 类描述： 创建人：dy 创建时间：2017-3-10 上午11:51:57
		 * 
		 */
		class ObjectFieldImpl implements FrameFieldInterface {
			@SuppressWarnings("hiding")
			public <T, K> void FrameFiledValues(Object object, DaoFramePameTransmission<T, K> daoFramePameTransmission) {
				// 全部的屬性 循環獲取每一個屬性
				for (Field field : daoFramePameTransmission.listFields) {
					field.setAccessible(true);
					/**
					 * 全部的列名字 对比 属性的名字
					 */
					String columnName = daoFramePameTransmission.getColumnNameMap().get(field.getName());
					String fieldName = field.getName();
					if (!WhetherToEmpty.StringWhetherToEmpty(columnName) && !field.getName().contains("extra_")
							&& WhetherToEmpty.ObjectWhetherToEmpty(field.getAnnotation(FrameExtraAttributes.class))) {
						/**
						 * 獲取集合數據列 的數據
						 */
						Object objectValue = daoFramePameTransmission.sqlRowSet.getObject(columnName);

						String string = field.getDeclaringClass().getName();
						Object object4 = daoFramePameTransmission.getBeanAttributes().get(string);

						if (WhetherToEmpty.ObjectWhetherToEmpty(objectValue)) {
							continue;
						}
						try {
							if ("double".equals(field.getType().getName())) {
								try {
									Double object2 = (Double) objectValue;
									field.set(object4, object2);
								} catch (Exception e) {
									BigDecimal object2 = (BigDecimal) objectValue;
									field.set(object4, object2);
								}
							} else {
								Object object2 = objectValue;// 數據庫對於的值
								field.set(object4, object2);
							}
						} catch (Exception e) {
							Log4j.Log4JOutError(e.getMessage() + " 列名：" + columnName + "\t bean属性名字" + fieldName
									+ "\t第" + daoFramePameTransmission.Counter + "行");
							continue;
						}
					}
					/**
					 * 分頁數據 總數統計
					 * 
					 */
					if (daoFramePameTransmission.pagingParametersCount == true) {
						fieldName = daoFramePameTransmission.getColumnNameMap().get("pagingParametersCount");
						if ("pagingParametersCount".equals(fieldName)) {
							Object objectValue = daoFramePameTransmission.sqlRowSet.getObject(fieldName);
							if (daoFramePameTransmission.getPagingParametersResult().getPagingParametersCount() <= 0) {
								daoFramePameTransmission.getPagingParametersResult().setPagingParametersCount(
										Integer.parseInt(objectValue.toString()));
							}
						}
					}
				}
			}
		}

		/**
		 * ClassA (a ,b,c,d,e,classB(b,c,e,g,h,q)) 註解類熟悉的反射
		 * 类名称：FrameAttributesFieldImpl 类描述： 创建人：dy 创建时间：2017-3-10 上午11:52:20
		 */
		class FrameAttributesFieldImpl implements FrameFieldInterface {
			@SuppressWarnings("hiding")
			@Override
			public <T, K> void FrameFiledValues(Object object, DaoFramePameTransmission<T, K> daoFramePameTransmission) {
				for (Field field : daoFramePameTransmission.listFields) {

					if (!WhetherToEmpty.ObjectWhetherToEmpty(field.getAnnotation(FrameAttributes.class))) {
						Object obj = daoFramePameTransmission.getBeanAttributes().get(field.getType().getName());
						if (!WhetherToEmpty.ObjectWhetherToEmpty(obj)) {
							try {
								field.set(object, obj);
							} catch (Exception e) {
								Log4j.Log4JOutError(e.getMessage());
								continue;
							}
						}
					}
				}
			}
		}

		FrameFiledexecute(new ObjectFieldImpl(), object, daoFramePameTransmission);
		FrameFiledexecute(new FrameAttributesFieldImpl(), object, daoFramePameTransmission);
	}

	private <T, K> void FrameFiledexecute(FrameFieldInterface fieldInterface, Object object,
			DaoFramePameTransmission<T, K> daoFramePameTransmission) {
		fieldInterface.FrameFiledValues(object, daoFramePameTransmission);
	}

	/**
	 * 關閉數據
	 */
	private <T, K> void colsDaoFramePameTransmission(DaoFramePameTransmission<T, K> daoFramePameTransmission) {
		daoFramePameTransmission.getColumnNameMap().clear();
		daoFramePameTransmission.getBeanAttributes().clear();
		daoFramePameTransmission.listFields.clear();
	}

	/**
	 * 返回 單個Object
	 */
	public <T, K> void ProcessorObject(DaoFramePameTransmission<T, K> daoFramePameTransmission) {
		SqlRowSet sqlRowSet = daoFramePameTransmission.sqlRowSet;
		SqlRowSetMetaData sqlRowSetMetaData = daoFramePameTransmission.sqlRowSet.getMetaData();
		/**
		 * 單個string
		 */
		if (DaoFrameUtil.queryClassIsUse(String.class, daoFramePameTransmission)) {
			String string = "";
			while (sqlRowSet.next()) {
				string = sqlRowSet.getString(1);
				break;
			}
			daoFramePameTransmission.getPagingParametersResult().pObject = string;
		}
		/**
		 * 一行string[]
		 */
		if (DaoFrameUtil.queryClassIsUse(String[].class, daoFramePameTransmission)) {
			String[] strings = new String[] {};
			int in = sqlRowSetMetaData.getColumnCount();
			while (sqlRowSet.next()) {
				for (int i = 1; i <= in; i++) {
					strings[i - 1] = sqlRowSet.getString(i);
				}
				break;
			}
			daoFramePameTransmission.getPagingParametersResult().pObject = strings;
		}
		/**
		 * 單個int
		 */
		if (DaoFrameUtil.queryClassIsUse(Integer.class, daoFramePameTransmission)) {
			Integer integer = 0;
			while (sqlRowSet.next()) {
				integer = sqlRowSet.getInt(1);
				break;
			}
			daoFramePameTransmission.getPagingParametersResult().pObject = integer;
		}
		/**
		 * 一行map
		 */
		if (DaoFrameUtil.queryClassIsUse(Map.class, daoFramePameTransmission)) {
			Map<String, Object> map = new HashMap<String, Object>();
			while (sqlRowSet.next()) {
				for (String string : sqlRowSetMetaData.getColumnNames()) {
					map.put(string, sqlRowSet.getObject(string));
				}
				break;
			}
			daoFramePameTransmission.getPagingParametersResult().pObject = map;
		}

	}
}
